package com.equipmentRent.web.controller.system;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import com.equipmentRent.common.utils.ShiroUtils;
import com.equipmentRent.system.domain.BizCart;
import com.equipmentRent.system.domain.Item;
import com.equipmentRent.system.domain.OrderDetail;
import com.equipmentRent.system.domain.VO.OrderDetailTopVo;
import com.equipmentRent.system.domain.VO.OrderDetailsVo;
import com.equipmentRent.system.domain.VO.OrderVo;
import com.equipmentRent.system.domain.VO.UserOrderListVo;
import com.equipmentRent.system.domain.dto.CreateOrderDto;
import com.equipmentRent.system.domain.dto.OrderIdDto;
import com.equipmentRent.system.domain.dto.OrderItemDto;
import com.equipmentRent.system.service.IBizCartService;
import com.equipmentRent.system.service.IItemService;
import com.equipmentRent.system.service.IOrderDetailService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.equipmentRent.common.annotation.Log;
import com.equipmentRent.common.enums.BusinessType;
import com.equipmentRent.system.domain.Order;
import com.equipmentRent.system.service.IOrderService;
import com.equipmentRent.common.core.controller.BaseController;
import com.equipmentRent.common.core.domain.AjaxResult;
import com.equipmentRent.common.utils.poi.ExcelUtil;
import com.equipmentRent.common.core.page.TableDataInfo;

import javax.annotation.Resource;

/**
 * 主订单Controller
 *
 * @author ruoyi
 * @date 2025-05-17
 */
@Controller
@RequestMapping("/system/order")
public class OrderController extends BaseController {
    private String prefix = "system/order";

    @Autowired
    private IOrderService orderService;

    @Resource
    private IItemService iItemService;

    @Resource
    private IOrderDetailService orderDetailService;

    @Resource
    private IBizCartService cartService;

    @RequiresPermissions("system:order:view")
    @GetMapping()
    public String order() {
        return prefix + "/order";
    }

    /**
     * 查询主订单列表
     */
    @RequiresPermissions("system:order:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(Order order) {
        startPage();
        List<OrderVo> list = orderService.selectOrderVoList(order);
        return getDataTable(list);
    }

    /**
 * 创建订单
 *
 * @param createOrderDto
 * @return
 */
@PostMapping("/createOrderInfo")
@ResponseBody
@Transactional
public AjaxResult createOrderInfo(@RequestBody CreateOrderDto createOrderDto) {
    if (createOrderDto == null
            || CollectionUtils.isEmpty(createOrderDto.getCarts())) {
        return AjaxResult.error("参数错误");
    }

    List<OrderItemDto> carts = createOrderDto.getCarts();

    // 初始化金额相关变量
    BigDecimal totalAmount = BigDecimal.ZERO;
    BigDecimal depositAmount = BigDecimal.ZERO;

    // 结果状态和消息
    boolean result = true;
    StringBuilder message = new StringBuilder("创建订单成功 订单号: ");

    // 创建订单主表
    Order order = new Order();
    String orderId = generateUniqueOrderNo();
    order.setId(orderId);
    order.setCustomerId(ShiroUtils.getUserId());
    order.setLeaseStart(new Date());
    // 设置归还时间为七天后
    order.setLeaseEnd(new Date(System.currentTimeMillis() + 7 * 24 * 60 * 60 * 1000));
    orderService.insertOrder(order);

    message.append(orderId);

    for (OrderItemDto item : carts) {
        BizCart bizCart = cartService.selectBizCartById(Long.parseLong(item.getCartId()));
        Long productId = bizCart.getProductId();
        Item domain = iItemService.selectItemById(productId);

        if (Objects.isNull(domain)) {
            message.setLength(0);
            message.append("参数错误：器材不存在");
            result = false;
            break;
        }

        int quantity = Integer.parseInt(item.getQuantity());
        if (domain.getAvailableStock() < quantity) {
            message.setLength(0);
            message.append("您所选的").append(domain.getName()).append("库存已不足，请适当减少租借数量");
            result = false;
            break;
        }

        // 计算费用
        BigDecimal dailyRate = item.getDailyRate();
        BigDecimal totalCost = dailyRate.multiply(BigDecimal.valueOf(quantity).multiply(BigDecimal.valueOf(7)));
        totalAmount = totalAmount.add(totalCost);

        // 计算押金
        BigDecimal deposit = domain.getDeposit().multiply(BigDecimal.valueOf(quantity));
        depositAmount = depositAmount.add(deposit);

        // 扣减库存
        domain.setAvailableStock(domain.getAvailableStock() - quantity);
        iItemService.updateItem(domain);

        // 插入子表
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orderId);
        orderDetail.setItemId(productId);
        orderDetail.setDailyRate(dailyRate);
        orderDetail.setQuantity(Long.valueOf(quantity));
        orderDetail.setDays(7L);
        orderDetailService.insertOrderDetail(orderDetail);
    }

    // 更新主表信息
    order.setTotalAmount(totalAmount);
    order.setDepositAmount(depositAmount);
    orderService.updateOrder(order);

    List<String> collect = carts.stream()
            .map(OrderItemDto::getCartId)
            .collect(Collectors.toList());
    // 清空购物车
    cartService.clearByIds(collect);

    if (result) {
        return AjaxResult.success(message.toString());
    } else {
        // 主动抛出异常触发事务回滚
        throw new RuntimeException(message.toString());
    }
}


    /**
     * 查询用户订单列表
     *
     * @return
     */
    @PostMapping("/queryUserOrderList")
    @ResponseBody
    public AjaxResult queryUserOrderList() {
        Long userId = ShiroUtils.getUserId();
        Order order = new Order();
        order.setCustomerId(userId);
        List<Order> orders = orderService.selectOrderList(order);
        if (CollectionUtils.isEmpty(orders)) {
            return AjaxResult.success("暂无订单");
        }
        List<UserOrderListVo> orderListVos = new ArrayList<>();
        orders.forEach(or -> {
            orderListVos.add(UserOrderListVo.builder()
                    .orderId(or.getId())
                    .totalAmount(or.getTotalAmount().add(or.getDepositAmount()))
                    .depositAmount(or.getDepositAmount())
                    .status(or.getStatus())
                    .leaseStart(or.getLeaseStart())
                    .leaseEnd(or.getLeaseEnd())
                    .build());
        });
        return AjaxResult.success(orderListVos);
    }


    /**
     * 查询订单详情
     * @param dto
     * @return
     */
    @PostMapping("/queryOrderDetails")
    @ResponseBody
    public AjaxResult queryOrderDetails(@RequestBody OrderIdDto dto) {
        if (StringUtils.isEmpty(dto.getOrderId())){
            return AjaxResult.error("请求参数错误");
        }
        List<OrderDetail> orderDetails = orderDetailService.selectOrderDetailByOrderId(dto.getOrderId());
        Order order = orderService.selectOrderById(dto.getOrderId());
        List<OrderDetailsVo> orderDetailsVos = new ArrayList<>();
        orderDetails.forEach(orderDetail -> {
            Item item = iItemService.selectItemById(orderDetail.getItemId());
            orderDetailsVos.add(OrderDetailsVo.builder()
                    .orderId(orderDetail.getOrderId())
                    .itemName(Optional.ofNullable(item).map(Item::getName).orElse("--"))
                    .imgUrl(Optional.ofNullable(item).map(Item::getImgUrl).orElse("--"))
                    .quantity(orderDetail.getQuantity().toString())
                    .dailyRate(orderDetail.getDailyRate().toString())
                    .days(orderDetail.getDays().toString())
                    .build());
        });
        OrderDetailTopVo orderDetailTopVo = new OrderDetailTopVo();
        orderDetailTopVo.setOrderId(order.getId());
        orderDetailTopVo.setTotalAmount(String.valueOf(order.getTotalAmount().add(order.getDepositAmount())));
        orderDetailTopVo.setDepositAmount(String.valueOf(order.getDepositAmount()));
        orderDetailTopVo.setLeaseStart(order.getLeaseStart().toString());
        orderDetailTopVo.setLeaseEnd(order.getLeaseEnd().toString());
        orderDetailTopVo.setOrderDetails(orderDetailsVos);
        return AjaxResult.success(orderDetailTopVo);
    }

    /**
     * 根据orderId获取该订单下商品列表
     * @param dto
     * @return
     */
    @PostMapping("/queryOrderItems")
    @ResponseBody
    public AjaxResult queryOrderItems(@RequestBody OrderIdDto dto) {
        if (StringUtils.isEmpty(dto.getOrderId())){
            return AjaxResult.error("请求参数错误");
        }
        List<OrderDetail> orderDetails = orderDetailService.selectOrderDetailByOrderId(dto.getOrderId());
        Order order = orderService.selectOrderById(dto.getOrderId());
        List<OrderDetailsVo> orderDetailsVos = new ArrayList<>();
        orderDetails.forEach(orderDetail -> {
            Item item = iItemService.selectItemById(orderDetail.getItemId());
            orderDetailsVos.add(OrderDetailsVo.builder()
                    .orderId(orderDetail.getOrderId())
                    .itemName(Optional.ofNullable(item).map(Item::getName).orElse("--"))
                    .imgUrl(Optional.ofNullable(item).map(Item::getImgUrl).orElse("--"))
                    .quantity(orderDetail.getQuantity().toString())
                    .dailyRate(orderDetail.getDailyRate().toString())
                    .days(orderDetail.getDays().toString())
                    .itemId(item.getId().toString())
                    .build());
        });
        return AjaxResult.success(orderDetailsVos);
    }


    //    写一个雪花算法生成主键的方法
    private static String generateUniqueOrderNo() {
    //生成DN开头的20位唯一订单号
        StringBuilder sb = new StringBuilder();
        sb.append("DN");
        sb.append(System.currentTimeMillis());
        sb.append(ThreadLocalRandom.current().nextInt(1000, 10000));
        return sb.toString();
    }


    /**
     * 导出主订单列表
     */
    @RequiresPermissions("system:order:export")
    @Log(title = "主订单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(Order order) {
        List<Order> list = orderService.selectOrderList(order);
        ExcelUtil<Order> util = new ExcelUtil<Order>(Order.class);
        return util.exportExcel(list, "主订单数据");
    }

    /**
     * 新增主订单
     */
    @GetMapping("/add")
    public String add() {
        return prefix + "/add";
    }

    /**
     * 新增保存主订单
     */
    @RequiresPermissions("system:order:add")
    @Log(title = "主订单", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(Order order) {
        return toAjax(orderService.insertOrder(order));
    }

    /**
     * 修改主订单
     */
    @RequiresPermissions("system:order:edit")
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") String id, ModelMap mmap) {
        Order order = orderService.selectOrderById(id);
        mmap.put("order", order);
        return prefix + "/edit";
    }

    /**
     * 修改保存主订单
     */
    @RequiresPermissions("system:order:edit")
    @Log(title = "主订单", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(Order order) {
        return toAjax(orderService.updateOrder(order));
    }

    /**
     * 删除主订单
     */
    @RequiresPermissions("system:order:remove")
    @Log(title = "主订单", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    @ResponseBody
    public AjaxResult remove(String ids) {
        return toAjax(orderService.softDeleteOrderByIds(ids));
    }
}
